package editor
{
	import Classes.pi_events;
	
	import UIFree.ObjectEvent;
	import UIFree.uif_component;
	import UIFree.uif_ecomponent;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;

	public class pi_rect extends uif_ecomponent {
		private var rect: uif_ecomponent;
		private var r_size: Point;
		private var _flips: Point;
		private var _roll: pi_roll;
		private var _resize: pi_resize;
		
		public function pi_rect(parent:uif_component, ax:int=0, ay:int=0, awidth:int=0, aheight:int=0) {
			var dw: Number = awidth / 2;
			var dh: Number = aheight / 2;
			super(parent, ax + dw, ay + dh, awidth, aheight);
			_flips = new Point(1, 1);
			
			addEvent(pi_events.VFLIPRELEASE, function(e: Event): void {
				_flips.y = -_flips.y;
				dispatchEvent(new Event(uif_component.RESIZE));
			}, app);
			addEvent(pi_events.HFLIPRELEASE, function(e: Event): void {
				_flips.x = -_flips.x;
				dispatchEvent(new Event(uif_component.RESIZE));
			}, app);
			
			addEvent(pi_events.GET_FLIPS, function(e: Event): void {
				app.dispatchEvent(new ObjectEvent(pi_events.FLIPSDATA, _flips));
			}, app);
			
			rect = new uif_ecomponent(this, -dw, -dh, awidth, aheight, 'rect');
			rect.addEvent(MouseEvent.MOUSE_DOWN, doDown);
			rect.addEvent(uif_component.RESIZE, function(e: Event): void {
				dispatchEvent(new Event(uif_component.RESIZE));
			});
			init_controls();
		}
		
		protected function refreshControls(e: Event=null): void {
			_roll.x = rect.width / 2;
			_roll.y = -rect.height / 2;
			_resize.x = rect.width / 2;
			_resize.y = rect.height / 2;
		}
		
		public function resizeOffset(delta: Number): void {
			var newSize: Point = new Point(rect.width, rect.height);
			newSize.x = r_size.x - r_size.x * delta / r_size.y; 
			newSize.y = r_size.y - r_size.y * delta / r_size.y;
			applyNewSize(newSize);
		}
		
		protected function applyNewSize(newSize: Point): void {
			if ((newSize.x > 10) && (newSize.y > 10)) {
				rect.x = -newSize.x / 2; 
				rect.y = -newSize.y / 2; 
				rect.resize(newSize.x, newSize.y);
				refreshControls();
			}
		}
				
		public function applySize(a_size: Point=null): void {
			if (a_size) applyNewSize(a_size);
			r_size = rect.size;
		}
		
		public function get RSize(): Point {
			return r_size;
		} 
		
		public function init_controls(): void {
			_roll = new pi_roll(this, x + width, y);
			_resize = new pi_resize(this, x + width, y + height);
			
			addEvent(uif_component.POSITION, refreshControls);
			addEvent(uif_component.RESIZE, refreshControls);
			
			var rotateStart: Point;
			var roll: Number = rotation;
			function rotate(e: MouseEvent): void {
				var v1: Point = rotateStart;
				var v2: Point = position.subtract(parentComponent.mousePos);
				var angle: Number = (Math.atan2(v1.x, v1.y) - Math.atan2(v2.x, v2.y)) / Math.PI * 180;
				
				rotateStart = v2;
				rotation += angle;
			}
			
			var resizeStart: Point;
			function scale(e: MouseEvent): void {
				var v: Point = position.subtract(parentComponent.mousePos);
				resizeOffset(resizeStart.length - v.length);
			}
			
			function removeMyEvent(e: MouseEvent): void {
				if (parent.hasEventListener(MouseEvent.MOUSE_MOVE)) { 
					parent.removeEventListener(MouseEvent.MOUSE_MOVE, rotate);
					parent.removeEventListener(MouseEvent.MOUSE_MOVE, scale);
					applySize();
				}
			}
			
			addEvent(MouseEvent.ROLL_OUT, function(e: MouseEvent): void {
				if (e.target == app) removeMyEvent(e);
			}, app);
			addEvent(MouseEvent.MOUSE_UP, removeMyEvent, app);
			
			_roll.addEvent(MouseEvent.MOUSE_DOWN, function(e: MouseEvent): void {
				rotateStart = position.subtract(parentComponent.mousePos);
//				roll		= rotation;
				parent.addEventListener(MouseEvent.MOUSE_MOVE, rotate);
			});
			_resize.addEvent(MouseEvent.MOUSE_DOWN, function(e: MouseEvent): void {
				resizeStart = position.subtract(parentComponent.mousePos);
				roll		= rotation;
				parent.addEventListener(MouseEvent.MOUSE_MOVE, scale);
			});
			refreshControls();
		}
		
		public function reset(a_size: Point): void {
			var dc: Point;
			var maxSize: Point = new Point(photo.source.width - 10, photo.source.height - 10);
			var minSize: Point = new Point(80, 80);
			if ((maxSize.x > 0) && (maxSize.y > 0)) {
				_flips.x = 1; 
				_flips.y = 1; 
				resize(a_size.x, a_size.y);
				if ((a_size.x > maxSize.x) || 
					(a_size.y > maxSize.y)) {
					dc = new Point(maxSize.x/a_size.x, maxSize.y/a_size.y);
					var maxdec: Number = (dc.x<dc.y)?dc.x:dc.y;
					a_size.x *= maxdec;
					a_size.y *= maxdec;
				}
				if ((a_size.x < minSize.x) || 
					(a_size.y < minSize.y)) {
					dc = new Point(minSize.x/a_size.x, minSize.y/a_size.y);
					var mindec: Number = (dc.x<dc.y)?dc.x:dc.y;
					a_size.x *= mindec;
					a_size.y *= mindec;
				}
				r_size = a_size;
				rect.x = -a_size.x / 2;
				rect.y = -a_size.y / 2;
				rect.resize(a_size.x, a_size.y);
				rotation = 0;
			}
		}
		
		protected function get photo(): pi_source {
			return (parent as pi_source);
		}
		
		public function getMatrix(): Matrix {
			var m:Matrix = new Matrix();
			var sl: Number = photo.sourceScale;
			
//			m.scale(sl, sl);
			m.translate((photo.source.x - x) / sl, (photo.source.y - y) / sl); // Трансляция к координатам фотографии
			
			m.scale(_flips.x, _flips.y);

			m.rotate(rotation / 360 * Math.PI * 2);

			m.translate(rect.width / 2 / sl, rect.height / 2 / sl);
			m.scale(width / rect.width, width / rect.width);
			return m;
		}
		
		public function offset(a_x: Number, a_y: Number): void {
			x += a_x * rect.width / width * _flips.x;
			y += a_y * rect.width / width * _flips.y;
		}
		
		private function doDown(e: MouseEvent): void {
			beginDrag(1);	
		}		
	}
}